package com.doraro.platform.module.device.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.doraro.platform.common.exception.ApiGlobalException;
import com.doraro.platform.module.device.mapper.RepairAdviceMapper;
import com.doraro.platform.module.device.model.entity.RepairAdvice;
import com.doraro.platform.module.device.model.entity.RepairOrder;
import com.doraro.platform.module.device.model.param.RepairAdviceParam;
import com.doraro.platform.module.device.service.IRepairAdviceService;
import com.doraro.platform.module.device.service.IRepairOrderService;
import com.doraro.platform.module.user.model.entity.SysJob;
import com.doraro.platform.module.user.service.ISysJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author doraro
 * @since 2019-04-27
 */
@Service
public class RepairAdviceServiceImpl extends ServiceImpl<RepairAdviceMapper, RepairAdvice> implements IRepairAdviceService {
    private final IRepairOrderService orderService;
    private final ISysJobService jobService;

    @Autowired
    public RepairAdviceServiceImpl(IRepairOrderService orderService, ISysJobService jobService) {
        this.orderService = orderService;

        this.jobService = jobService;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void choiceAdvice(String orderId, Integer adviceId, String userId) {
        Objects.requireNonNull(orderId);
        Objects.requireNonNull(adviceId);

        //验证orderId
        orderService.getUnresolvedOrder(orderId, userId);

        //验证solutionId
        final RepairAdvice solution = super.getById(adviceId);
        if (solution == null || !solution.getOrderId().equals(orderId)) {
            throw new ApiGlobalException("解决方案不存在");
        }
        //查看工程师是否在任务中
        final String engineerId = solution.getEngineerId();
        final SysJob working = jobService.unCompleteJob(engineerId);

        if (working != null) {
            throw new ApiGlobalException("工程师正在工作中,请选择其他工程师!");
        }
        //选择意见
        this.updateAdvice(orderId, adviceId);

        //修改订单状态，并添加engineer_id manager_id dispatch_time
        orderService.setOrderMaintain(orderId, engineerId, userId);
        //生成工程师任务
        jobService.createNewJob(orderId, engineerId);



    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer saveOrUpdateAdvice(String engineerId, RepairAdviceParam solution) {
        Objects.requireNonNull(engineerId);
        Objects.requireNonNull(solution);
        final RepairAdvice advice = solution.convert(RepairAdvice.class);
        advice.setEngineerId(engineerId).setSStatus(0);

        final String orderId = advice.getOrderId();
        final RepairOrder order = orderService.getById(orderId);
        if (order == null) {
            throw new ApiGlobalException("不存在相应的order_id");
        }
        if (advice.getId() == null) {
            super.save(advice);
            return advice.getId();
        }

        final RepairAdvice oldAdvice = super.getById(advice.getId());
        //未找到或已被拒绝
        if (oldAdvice == null || oldAdvice.getSStatus() != 0) {
            throw new ApiGlobalException("不存在相应的advice");
        }
        if (!oldAdvice.getEngineerId().equals(advice.getEngineerId())) {
            throw new ApiGlobalException(HttpStatus.FORBIDDEN.value(), "无权操作");
        }
        super.updateById(advice);
        return oldAdvice.getId();
    }

    private void updateAdvice(String orderId, Integer adviceId) {
        this.rejectAdvice(orderId);
        super.lambdaUpdate()
                .eq(RepairAdvice::getOrderId, orderId)
                .eq(RepairAdvice::getId, adviceId)
                .set(RepairAdvice::getSStatus, 1)
                .update();
    }

    @Override
    public void rejectAdvice(String orderId) {
        super.lambdaUpdate()
                .eq(RepairAdvice::getOrderId, orderId)
                .set(RepairAdvice::getSStatus, 2)
                .update();

    }
}
